package security;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

public class KeyDerivation {

	/**
	 * PBKDF2, algorithme de dérivation de clé.
	 * see http://www.javacodegeeks.com/2012/05/secure-password-storage-donts-dos-and.html
	 * @param password
	 * @param salt
	 * @param derivedKeyLength
	 * @param iterations
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 */
	public static byte[] PBKDF2(String password, byte[] salt, int derivedKeyLength, int iterations)
			throws NoSuchAlgorithmException, InvalidKeySpecException {
		String algorithm = "PBKDF2WithHmacSHA1";
		
		KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength);
		
		SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm);
		
		return f.generateSecret(spec).getEncoded();
	}
	
	
	// tests
	public static void main(String[] args) {
		String plainTextPWD = "Toto1234&§";
		byte[] salt = {32, -27, 24, 50, -121, 24, 27, -39}; // static pour les tests
		byte[] PIN1 = null;
		
		try {
			//salt = RandomGenerator.generateSalt(8);
			long start = System.currentTimeMillis();
			
			// 200000 iterations prennent plus ou moins 1 seconde
			PIN1 = KeyDerivation.PBKDF2(plainTextPWD, salt, 32, 10000);
			System.out.println("Total time: "+(System.currentTimeMillis() - start)+" ms");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println("Plain text pwd: "+plainTextPWD);
		System.out.print("PIN1 dérivé: ");
		for(int i=0; i<PIN1.length; i++)
			System.out.print(PIN1[i]+" ");
		System.out.println();
	}

}
